﻿using GameToolkit.BehaviourTree;

namespace GameToolkit
{
    [System.Serializable]
    [CompositeCategory("")]
    [CompositeTitle("联合任务", Description = "Union Tasks")]
    [TaskResult("Success", (int)EReservedTaskResult.Finish, "#00ff00")]
    [TaskResult("Failed", (int)EReservedTaskResult.GiveUp, "#ff0000")]
    [HideTaskNodePort(HideGiveUpInput = true)]
    public class UnionTaskNode : TaskNode
    {
        public override TaskEntity Create()
        {
            return new Impl();
        }

        public class Impl : TaskEntity
        {
            TaskEntity[] mLst;
            //TaskGraph mGraph;

            protected override void OnEnter(TaskGraph graph)
            {
                if (State == ETaskState.Complete && ResultValue == (int)EReservedTaskResult.GiveUp)
                    return;
                //if (State == ETaskState.Inactive)
                //{
                //mGraph = graph;
                var prec = Node.PreconditionCount;
                if (mLst == null || mLst.Length != prec)
                    mLst = new TaskEntity[prec];
                for (int i = 0; i < prec; i++)
                {
                    mLst[i] = graph.GetEntity(Node.GetPrecondition(i).node);
                    if (mLst[i] != null)
                        mLst[i].OnStateChanged += OnTaskChanged;
                }
                OnTaskChanged(null);
                //}
            }

            protected override void OnExit(TaskGraph graph)
            {
                if (mLst != null)
                {
                    for (int i = 0; i < mLst.Length; i++)
                    {
                        if (mLst[i] != null)
                            mLst[i].OnStateChanged -= OnTaskChanged;
                    }
                }
            }

            void OnTaskChanged(TaskEntity entity)
            {
                bool success = true;
                for (int i = 0; i < mLst.Length; i++)
                {
                    var stat = mLst[i] == null ? ETaskState.Complete : mLst[i].State;
                    if (stat <= ETaskState.Processing)
                    {
                        SetState(ETaskState.Processing, 0);
                        return;
                    }
                    else if (success)
                    {
                        var prec = Node.GetPrecondition(i);
                        success = prec.IsTrue(mLst[i]);
                    }
                }
                var code = success ? EReservedTaskResult.Finish : EReservedTaskResult.GiveUp;
                SetState(ETaskState.Complete, (int)code);
            }
        }
    }

    [System.Serializable]
    [CompositeCategory("")]
    [CompositeTitle("FINAL TASK", Description = "结束所有任务")]
    sealed public class FinalTaskNode : TaskNode
    {
        public override TaskEntity Create()
        {
            return null;
        }
    }
}
